<?php

namespace App\Http\Controllers\Admin\System;

use App\Enums\ResponseEnum;
use App\Http\Controllers\AdminController;
use App\Models\System\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Str;
use Illuminate\Validation\Rules\Password;

class UserController extends AdminController
{
    public function data(Request $request)
    {
        $model = User::query()->select(['id', 'avatar', 'username', 'display_name', 'status', 'created_at', 'updated_at']);
        if ($keywords = $request->get('keywords')) {
            $keywordType = $request->get('keywordType');
            if (!empty($keywordType) && $keywordType === 'username') {
                $model->where('username', 'like', $keywords.'%');
            }else {
                $model->where('display_name', 'like', $keywords.'%');
            }
        }
        $total = $model->count();
        $page = (int)$request->get('page', 1);
        $pageSize = (int)$request->get('pageSize', 10);
        $list = $model->with('roles:id')->offset(($page - 1) * $pageSize)->limit($pageSize)->get();
        $data = $list->toArray();
        if (!empty($data)) {
            foreach ($list as $key => $value) {
                if ($value['roles']) {
                    $data[$key]['roles'] = $value->roles->pluck('id');
                }
            }
        }
        return $this->succeed([
            'total' => $total,
            'rows'  => $list,
        ]);
    }

    public function store(Request $request)
    {
        $request->validate([
            'username' => ['required','between:3,15','unique:users'],
            'display_name' => ['required','between:2,20'],
            'status' => ['nullable','integer','in:0,1'],
            'password' => ['required', 'between:8,20', 'confirmed', Password::default()],
            'roles' => ['required','array'],
        ]);
        $data = $request->only(['avatar', 'username', 'display_name', 'password', 'status', 'roles']);
        DB::beginTransaction();
        try {
            $model = User::query()->create([
                'avatar' => (string)$data['avatar'],
                'username' => $data['username'],
                'display_name' => $data['display_name'],
                'password' => bcrypt($data['password']),
                'status' => (int)$data['status'],
                'uuid' => Str::uuid(),
            ]);
            if (!empty($data['roles'])) {
                $model->roles()->attach($data['roles']);
            }
            $this->createSyslog('添加了一条管理员账号记录', $data, $model);
            DB::commit();
            $item = $model->toArray();
            return $this->succeed([
                'id' => $model['id'],
                'created_at' => $item['created_at'],
                'updated_at' => $item['updated_at']
            ]);
        } catch (\Exception) {
            DB::rollBack();
        }
        return $this->fail();
    }

    public function update(Request $request, $id)
    {
        $request->validate([
            'username' => ['required','between:3,15','unique:users,username,'.$id.',id'],
            'display_name' => ['required','between:2,20'],
            'status' => ['nullable','integer','in:0,1'],
            'roles' => ['required','array'],
        ]);
        $model = User::query()->findOrFail($id);
        $data = $request->only(['avatar', 'username', 'display_name', 'status', 'roles']);
        DB::transaction(function () use ($model, $data) {
            $model->update([
                'avatar' => (string)$data['avatar'],
                'username' => $data['username'],
                'display_name' => $data['display_name'],
                'status' => (int)$data['status'],
            ]);
            if (!empty($data['roles'])) {
                $model->syncRoles($data['roles']);
            }
            $this->createSyslog('更新了一条管理员账号记录', $data, $model);
        });
        return $this->succeed();
    }

    public function resetPassword(Request $request, $id)
    {
        $request->validate([
            'password' => ['required', 'max:20', Password::default()]
        ]);
        $model = User::query()->findOrFail($id);
        $password = $request->get('password');
        DB::transaction(function () use ($model, $password) {
            $model->update(["password" => bcrypt($password)]);
            $this->createSyslog('重置了管理员账号的密码', [], $model);
        });
        return $this->succeed();
    }

    public function destroy(Request $request)
    {
        $request->validate(['ids' => ['required','array','max:'.static::QUERY_LIMIT]]);
        $ids = $request->get('ids');
        abort_if(in_array(1, $ids, true), ResponseEnum::USER_EXISTS_DELETE_ERROR);
        $list = User::query()->select(['id'])->whereIn('id', $ids)->limit(static::QUERY_LIMIT)->withCount('roles')->get();
        abort_if($list->isEmpty(), ResponseEnum::DELETE_NOT_EXIST_ERROR);
        DB::transaction(function () use ($list) {
            foreach ($list as $row) {
                if ($row->roles_count > 0) {
                    $row->roles()->detach();
                }
                $row->delete();
                $this->createSyslog('删除了一条管理员账号记录', [], $row);
            }
        });
        return $this->succeed();
    }
}
